py-spy 的用法

py-spy 的用法

py-spy 命令概览

版本: 0.4.0
用途: Python 程序的采样分析器

子命令 说明
record 记录堆栈轨迹信息,生成火焰图、speedscope 或原始文件
top 以类 top 视图显示消耗 CPU 的函数
dump 将目标程序的堆栈轨迹输出到 stdout
help 打印帮助信息

top 子命令

用途:以类 top 视图显示消耗 CPU 的函数

选项 默认值 说明
-p, --pid <pid> 要监控的正在运行的 Python 进程 PID
-r, --rate <rate> 100 每秒采集的样本数
-s, --subprocesses 分析原进程的子进程
--full-filenames 显示完整的 Python 文件名,而非只显示包名部分
-g, --gil 仅包含持有 GIL 的轨迹
-i, --idle 包含空闲线程的堆栈轨迹
--delay <seconds> 1.0 top 刷新间隔(秒)
-n, --native 收集来自 Cython、C 或 C++ 编写的原生扩展的堆栈轨迹
--nonblocking 采样时不暂停 Python 进程。此选项可降低采样对性能的影响,但可能导致结果不准确
-h, --help 打印帮助信息

record 子命令

用途:记录堆栈轨迹信息,生成火焰图、speedscope 或原始文件

选项 默认值 说明
-p, --pid <pid> 要记录的正在运行的 Python 进程 PID
--full-filenames 显示完整的 Python 文件名,而非只显示包名部分
-o, --output <filename> 输出文件名
-f, --format <format> flamegraph 输出文件格式(可选:flamegraph, raw, speedscope, chrometrace)
-d, --duration <duration> 无限制 采样的总秒数
-r, --rate <rate> 100 每秒采集的样本数
-s, --subprocesses 分析原进程的子进程
-F, --function 按函数的首行号聚合样本,而非当前行号
--nolineno 不显示行号
-t, --threads 在输出中显示线程 ID
-g, --gil 仅包含持有 GIL 的轨迹
-i, --idle 包含空闲线程的堆栈轨迹
-n, --native 收集来自 Cython、C 或 C++ 编写的原生扩展的堆栈轨迹
--nonblocking 采样时不暂停 Python 进程。此选项可降低采样对性能的影响,但可能导致结果不准确
-h, --help 打印帮助信息

基础监控命令

1. 监控运行中的 Python 进程

# 查看 PID 为 12345 的 Python 进程的 CPU 使用情况(类似 top 命令)
sudo py-spy top -p 12345

# 每 2 秒刷新一次
sudo py-spy top -p 12345 --delay 2

2. 从启动开始监控 Python 程序

# 启动 Python 脚本并实时监控
sudo py-spy top -- python my_script.py arg1 arg2

# 监控 Django 开发服务器
sudo py-spy top -- python manage.py runserver

3. 生成性能火焰图

# 对运行中的进程采样 30 秒,生成火焰图
sudo py-spy record -p 12345 -d 30 -o flamegraph.svg

# 采样 10 秒,使用 speedscope 格式(适合 Web 交互式分析)
sudo py-spy record -p 12345 -d 10 -f speedscope -o profile.speedscope.json

4. 分析完整调用链(包括 C 扩展)

# 包含 Python 和 C/C++/Cython 扩展的堆栈
sudo py-spy record -p 12345 --native -o profile.svg

# 包含子进程分析
sudo py-spy record -p 12345 -s --native -o profile.svg

高级分析命令

5. 分析特定时间段的性能

# 高频率采样(500Hz),持续 5 秒
sudo py-spy record -p 12345 -r 500 -d 5 -o high_freq.svg

# 采样 1 分钟,按函数聚合而非行号
sudo py-spy record -p 12345 -d 60 -F -o by_function.svg

6. GIL 竞争分析

# 只显示持有 GIL 的调用堆栈(分析 GIL 竞争)
sudo py-spy top -p 12345 -g

# 记录 GIL 持有者的火焰图
sudo py-spy record -p 12345 -g -o gil_profile.svg

7. 线程分析

# 显示所有线程(包括空闲线程)
sudo py-spy top -p 12345 -i

# 火焰图中区分不同线程
sudo py-spy record -p 12345 -t -o threads.svg

8. 生产环境友好命令

# 使用非阻塞模式,减少对生产服务的影响
sudo py-spy record -p 12345 --nonblocking -d 60 -o prod_profile.svg

# 后台运行并输出到文件
sudo py-spy record -p 12345 -d 120 -o /tmp/profile_$(date +%Y%m%d_%H%M%S).svg &

实用组合命令

9. 查找性能瓶颈

# 监控并实时查看最耗时的函数
sudo py-spy top -p 12345 --full-filenames

# 生成详细调用链火焰图
sudo py-spy record -p 12345 --full-filenames --native -o detailed.svg

10. 调试命令

# 快速查看进程当前堆栈
sudo py-spy dump -p 12345

# 监控 Flask/Django 请求处理
sudo py-spy top -- python app.py
# 然后在浏览器访问应用,观察 CPU 使用变化

容器环境使用

# 在 Docker 容器内运行
docker exec -it <container_id> py-spy top -p 1

# 从宿主机监控容器进程
sudo py-spy top -p $(pgrep -f "python my_app")

常用参数组合总结

场景 推荐命令
快速查看性能热点 sudo py-spy top -p <PID>
生成火焰图报告 sudo py-spy record -p <PID> -d 30 -o profile.svg
分析包含 C 扩展 sudo py-spy record -p <PID> --native -o profile.svg
生产环境采样 sudo py-spy record -p <PID> --nonblocking -d 60 -o profile.svg
分析 GIL 竞争 sudo py-spy top -p <PID> -g
详细调用链分析 sudo py-spy record -p <PID> --full-filenames --native -o detailed.svg

注意事项

  1. 通常需要 sudo 权限
  2. 采样时间不宜过短(建议至少 10-30 秒)
  3. 生产环境使用 --nonblocking 减少影响
  4. 分析完成后用浏览器打开 .svg 文件查看火焰图